//package com.game.netty;
//
//
//import com.game.net.Connect;
//import com.game.net.ConnectListener;
//import com.game.net.NetAddress;
//import com.game.timer.TimerCenter;
//import com.game.timer.TimerEvent;
//import com.game.timer.TimerListener;
//import io.netty.bootstrap.Bootstrap;
//import io.netty.channel.ChannelFuture;
//import io.netty.channel.ChannelFutureListener;
//import io.netty.channel.ChannelHandler;
//import io.netty.channel.ChannelInitializer;
//import io.netty.channel.ChannelOption;
//import io.netty.channel.EventLoopGroup;
//import io.netty.channel.nio.NioEventLoopGroup;
//import io.netty.channel.socket.nio.NioSocketChannel;
//import io.netty.util.concurrent.Future;
//import io.netty.util.concurrent.GenericFutureListener;
//import java.util.List;
//import java.util.Random;
//import java.util.concurrent.CopyOnWriteArrayList;
//import java.util.concurrent.TimeUnit;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//public class ConnectPool<T extends NettyConnect> implements ConnectListener, TimerListener, ChannelFutureListener {
//    public static final int MAX_POOL_SIZE = 10;
//
//    public static final int POOL_SIZE = 2;
//
//    private Logger log = LoggerFactory.getLogger(getClass());
//
//    private NetAddress netAddress;
//
//    private NetAddress localAddress;
//
//    private ChannelInitializer initializer;
//
//    private int poolSize;
//
//    private Bootstrap bootstrap;
//
//    private List<T> connectList;
//
//    private Random random = new Random();
//
//    private TimerCenter timerCenter;
//
//    public ConnectPool(NetAddress netAddress, ChannelInitializer initializer) {
//        this(netAddress, null, initializer, 2);
//    }
//
//    public ConnectPool(NetAddress netAddress, NetAddress localAddress, ChannelInitializer initializer) {
//        this(netAddress, localAddress, initializer, 2);
//    }
//
//    public ConnectPool(NetAddress netAddress, NetAddress localAddress, ChannelInitializer initializer, int poolSize) {
//        this.netAddress = netAddress;
//        this.initializer = initializer;
//        this.poolSize = poolSize;
//        this.localAddress = localAddress;
//    }
//
//    public ConnectPool init() {
//        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
//        this.bootstrap = new Bootstrap();
//        ((Bootstrap)((Bootstrap)((Bootstrap)this.bootstrap.group((EventLoopGroup)nioEventLoopGroup)).channel(NioSocketChannel.class)).option(ChannelOption.SO_KEEPALIVE, Boolean.valueOf(true)))
//                .handler((ChannelHandler)this.initializer);
//        this.bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Integer.valueOf(5000));
//        if (this.localAddress != null)
//            this.bootstrap.localAddress(this.localAddress.getHost(), this.localAddress.getPort());
//        this.bootstrap.remoteAddress(this.netAddress.getHost(), this.netAddress.getPort());
//        this.connectList = new CopyOnWriteArrayList<>();
//        return this;
//    }
//
//    public ConnectPool start(TimerCenter timerCenter) {
//        this.log.debug("start net={}", this.netAddress);
//        if (timerCenter != null) {
//            this.timerCenter = timerCenter;
//            timerCenter.add((new TimerEvent(this, "", 30, 2147483647, 5)).withTimeUnit(TimeUnit.SECONDS));
//        }
//        return this;
//    }
//
//    public void addConnect(T connect) {
//        this.connectList.add(connect);
//        connect.addConnectListener(this);
//    }
//
//    public T getConnect() throws InterruptedException {
//        if (this.connectList.isEmpty()) {
//            create();
//            return null;
//        }
//        if (this.connectList.size() == 1)
//            return this.connectList.get(0);
//        int index = this.random.nextInt(this.connectList.size());
//        return this.connectList.get(index);
//    }
//
//    public T getConnectSync() throws InterruptedException {
//        NettyConnect nettyConnect = null;
//        T c = getConnect();
//        if (c == null) {
//            nettyConnect = (NettyConnect)this.bootstrap.connect().sync().channel().pipeline().get(NettyConnect.class);
//            this.connectList.add((T)nettyConnect);
//        }
//        return (T)nettyConnect;
//    }
//
//    private void create() {
//        this.log.debug("开始创建连接，address{}", this.netAddress);
//        this.bootstrap.connect().addListener((GenericFutureListener)this);
//    }
//
//    public void close(Connect connect) {
//        this.connectList.remove(connect);
//    }
//
//    public void onConnectClose(Connect connect) {
//        this.connectList.remove(connect);
//    }
//
//    public void onTimer(TimerEvent e) {
//        if (this.connectList.size() < 2)
//            create();
//    }
//
//    public void operationComplete(ChannelFuture cf) throws Exception {
//        if (cf.isSuccess()) {
//            NettyConnect nettyConnect = (NettyConnect)cf.channel().pipeline().get(NettyConnect.class);
//            nettyConnect.addConnectListener(this);
//        } else {
//            if (cf.channel() != null)
//                cf.channel().close();
//            this.log.warn("连接创建失败", cf.cause());
//        }
//    }
//
//    public void shutdown() {
//        this.log.info("连接池关闭");
//        if (this.timerCenter != null) {
//            this.timerCenter.remove(this);
//            for (Connect connect : this.connectList) {
//                try {
//                    connect.close();
//                } catch (Exception e) {
//                    this.log.warn("连接池关闭失败", e);
//                }
//            }
//            this.connectList.clear();
//        }
//    }
//}
